;;; init-eshell.el --- Eshell configuration -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:

(with-eval-after-load 'eshell
  (add-to-list 'eshell-modules-list 'eshell-rebind)

  (setenv "TERM" "xterm-256color")

  (defun eshell/z (&optional regexp)
    "Navigate to a previously visited directory in eshell, or to
any directory proferred by `consult-dir'."
    (let ((eshell-dirs (delete-dups
                        (mapcar 'abbreviate-file-name
                                (ring-elements eshell-last-dir-ring)))))
      (require 'consult-dir)
      (cond
       ((not regexp)
        (let* ((consult-dir--source-eshell `(:name "Eshell"
                                                   :narrow ?e
                                                   :category file
                                                   :face consult-file
                                                   :items ,eshell-dirs))
               (consult-dir-sources (cons consult-dir--source-eshell
                                          consult-dir-sources)))
          (eshell/cd (substring-no-properties
                      (consult-dir--pick "Switch directory: ")))))
       (t (eshell/cd (if regexp (eshell-find-previous-directory regexp)
                       (completing-read "cd: " eshell-dirs)))))))
  )

(with-eval-after-load 'esh-proc
  (defun eshell-command-alert (process status)
    "Send `alert' with severity based on STATUS when PROCESS finished."
    (let* ((cmd (process-command process))
           (buffer (process-buffer process))
           (msg (replace-regexp-in-string "\n" " " (format "%s: %s" (mapconcat 'identity cmd " ")  status)))
           (buffer-visible (member buffer (mapcar #'window-buffer (window-list)))))
      (unless buffer-visible
        (message "%s %s"
                 (propertize (buffer-name buffer))
                 (propertize msg)))))

  (add-hook 'eshell-kill-hook #'eshell-command-alert))


(with-eval-after-load 'esh-mode
  (defun ctrlwei/eshell-clear-buffer ()
    "Clear eshell buffer content."
    (interactive)
    (let ((inhibit-read-only t))
      (erase-buffer)
      (eshell-send-input)))

  (defun ctrlwei/eshell-comint-history ()
    "eshell & comint history with ido."
    (interactive)
    (if (or (member major-mode '(eshell-mode sql-interactive-mode))
            (derived-mode-p 'comint-mode))
        (let ((ring (if (eq major-mode 'eshell-mode)
                        eshell-history-ring
                      comint-input-ring)))
          (insert
           (completing-read "History: "
                            (delete-dups
                             (ring-elements ring)))))
      (message "Unsupported mode")))

  (define-key eshell-mode-map (kbd "M-l") #'ctrlwei/eshell-clear-buffer)
  (define-key eshell-mode-map (kbd "C-c C-l") #'ctrlwei/eshell-comint-history)
  (advice-add 'eshell-life-is-too-much :override #'ctrlwei/quit-window))

(provide 'init-eshell)
;;; init-eshell.el ends here
